import abc  # 利用abc模块实现抽象类
import logging
from datetime import datetime

from .DownloadInfo import DownloadInfo


class ContentSpiderDriver(metaclass=abc.ABCMeta):

    @abc.abstractmethod
    def type_name(self) -> str:
        """
        此Driver的类型名称，用于标识不同的Driver
        :return: 类型名称字符串
        """
        pass

    @abc.abstractmethod  # 定义下载内容的抽象方法
    def download_content(self, content_download_info: DownloadInfo, dir_path: str):
        """
        下载内容
        :param content_download_info: 这个变量记录了下载所需的信息
        :param dir_path: 将下载的内容放到这个文件夹中
        """
        pass


class ContentSpider:
    """
    在指定的目录下下载内容
    """

    def __init__(self):
        self.drivers = {}

    def add_driver(self, driver: ContentSpiderDriver):
        """
        添加Driver
        :param driver: 要添加的ContentSpiderDriver
        """
        t = driver.type_name()
        if t in self.drivers:
            logging.warning("ContentSpiderDriver %s 已存在" % t)
        self.drivers[t] = driver
        logging.info("ContentSpiderDriver %s 已添加" % t)

    def download_content(self, download_info: DownloadInfo, dir_path: str):
        """
        下载内容
        :param download_info: 这个变量记录了下载所需的信息
        :param dir_path: 将内容下载到这个文件夹里面
        """
        type_name = download_info.driver_type_name
        if type_name in self.drivers:
            logging.info("让 ContentSpiderDriver %s   处理 download_info %s" %
                         (type_name, download_info.serialize()))
            try:
                self.drivers[type_name].download_content(download_info, dir_path)
                download_info.last_updated_time = datetime.now()
                logging.info("ContentSpiderDriver %s 已下载 download_info %s 对应内容" %
                             (type_name, download_info.serialize()))
            except Exception as e:
                logging.error("ContentSpiderDriver %s 下载 download_info %s 对应元数据时发生错误: %s" %
                              (type_name, download_info.serialize(), str(e)))
        else:
            logging.warning("找不到 type_name = %s 的 ContentSpiderDriver" % type_name)
